from pymongo import MongoClient
class Tt:
    def __init__(self):
        client = MongoClient('127.0.0.1',27017)
        db = client['test']
        self.coll = db['test']
    def insertDoc(self,doc): #创建单个文档
        try: # 尝试这段代码
            # 当cno相同的文档存在于集合中时，应该抛出异常不去执行insert_one
            # count_documents(query) 根据查询条件统计文档条数，不具体查询内容            
            if self.coll.count_documents({'cno':doc['cno']})>0:
                #抛出异常，try里面剩余代码不会继续执行了
                # 异常有很多如 typeError valueError IoError IndexError
                raise IndexError('该课程已存在，请勿重复插入')
            return self.coll.insert_one(doc)
        except IndexError as e:# 捕获IndexError错误
            print(e)
        except Exception as err: # 捕获所有错误
            print(f"插入单条数据出错：{err}")
    
    def insertDocs(self,docs):#创建多个文档
        try:
            if self.coll.count_documents({'cno':docs[0]['cno']})>0:
                raise IndexError('该课程已存在，请勿重复插入')
            return self.coll.insert_many(docs)
        except Exception as Err:
            print(f'插入多条数据出错{Err}')

    def insertDocsM(self,docs):#创建多个文档
        try:
            for doc in docs:
                if  self.coll.count_documents('cno',docs['cno'])>0:
                    raise IndexError(cno,'该课程已存在，请勿重复插入')
                return self.coll.insert_one(doc)
        except Exception as Err:
            print(f'批量插入数据出错：{Err}')
    def updateDocs(self,query,params):# 修改多个文档
        try:
            return self.coll.update_many(query,params)
        except Exception as Err:
            print(f'修改文档出错：{Err}')
    def deleteDocs(self,query): # 删除多个文档
        try:
            return self.coll.delete_many(query)
        except Exception as Err:
            print(f'删除文档出错：{Err}')
    # query=None表示如果没有传query这个值默认为None find查询时默认查询全部内容
    # 缺省值===默认值
    def findDocs(self,query=None): # 根据条件查找文档
        return list(self.coll.find(query))
    def aggDocs(self,pipeline): # 根据管道操作文档
        try:
            return list(self.coll.aggregate(pipeline))
        except Exception as Err:
            print(f'管道操作文档出错：{Err}')
if __name__ =='__main__':
    tt = Tt() # 对象的实例化
    print("---插入一条数据---")
    # 在test数据库中tt集合里面插入一条数据 {course:"语文"，redit:10}
    # 读出这条数据
    tt.insertDoc({'cno':'001','course':"语文",'redit':10})
    print(tt.findDocs())

    # 在test数据库中tt集合里面插入多条数据 三条 有course和redit
    # 读出所有数据
    print("---插入多条数据---")    
    ds=[
        {'cno':'002','course':"英语",'redit':9},
        {'cno':'003','course':"数学",'redit':15},
        {'cno':'004','course':'生物','redit':8}
    ]
    tt.insertDocs(ds)
    print(tt.findDocs())

    # 修改course为语文的redit值为12
    # 读出 course为语文的文档
    print("---修改数据---")
    tt.updateDocs({'course':"语文"},{"$inc":{"redit":2}})
    tt.updateDocs({'course':"语文"},{"$set":{"redit":12}})
    print(tt.findDocs({'course':'语文'}))
    
    # 删除redit>10的文档
    # 删除没有cno的文档
    # 读出所有数据
    print("---删除数据---")
    tt.deleteDocs({'redit':{'$gt':10}})
    tt.deleteDocs({'cno':{'$exists':False}})
    print(tt.findDocs())
    print("---管道操作---")
    # 管道操作，计算出所有课成redit的总分
    pipeline = [
        {
            '$group':{
                '_id':None,
                '总分':{'$sum':'$redit'}
            }
        }
    ]
    print(tt.aggDocs(pipeline))